#include "SceneObject.h"

SceneObject::SceneObject()
{
    x = y = z = 0.0f;
    scale_x = scale_y = scale_z = 1.0f;
    rotation_x = rotation_y = rotation_z = 0.0f;
    offset_x = offset_y = offset_z = 0.0f;
    visible = eventable = updatable = true;
    parent = 0;
}

SceneObject::~SceneObject()
{
    // Parent has to exist in order the children to be moved to the grandparent
    // and for the object to be removed from the parent's children.
    if (parent != 0)
    {
        // Move all children to their grandparent
        for(unsigned int i = 0; i < children.size(); i++)
            parent->addChild(children[i]);

        // Remove this object from parent
        parent->removeChild(this);
    }
}

void SceneObject::addChild(SceneObject* child)
{
    child->parent = this;
    children.push_back(child);
}

void SceneObject::removeChild(SceneObject* child)
{
    child->parent = 0;
    // Loop through children and remove this child
    for(unsigned int i = 0; i < children.size(); i++)
    {
        if(children[i] == child)
        {
            // Erase child at index i
            children.erase(children.begin()+i);
            return;
        }
    }
}

void SceneObject::removeChildren()
{
    for(unsigned int i = 0; i < children.size(); i++)
        children[i]->parent = 0;
    children.erase(children.begin(),children.end());
}

void SceneObject::deleteChild(SceneObject* child){ delete child; }

void SceneObject::deleteChildren()
{
    while(children.size() > 0)
    {
        children[0]->deleteChildren();
        delete children[0];
    }
}

float SceneObject::getGlobalX()
{
    if (parent == 0)
        return x;
    return x + parent->getGlobalX();
}


float SceneObject::getGlobalY()
{
    if (parent == 0)
        return y;
    return y + parent->getGlobalY();
}

void SceneObject::drawRecursive(bool ignoreSelf, bool ignoreChildren)
{
    if(visible)
    {
        // Create matrix for this object
        glPushMatrix();
        // Position this object
        glTranslatef(x, y, z);
        // Rotate X, Y, Z
        glRotatef(rotation_x, 1.0f, 0.0f, 0.0f);
        glRotatef(rotation_y, 0.0f, 1.0f, 0.0f);
        glRotatef(rotation_z, 0.0f, 0.0f, 1.0f);
        // Scale the object
        glScalef(scale_x,scale_y,scale_z);
        // Offset the object
        glTranslatef(offset_x, offset_y, offset_z);
        // Now draw self
        if(!ignoreSelf)
            draw();
        // Loop through each child...
        if(!ignoreChildren)
        {
            for(unsigned int i = 0; i < children.size(); i++)
            {
                // Draw child recursively
                children[i]->drawRecursive(false,false);
            }
        }
        // Remove this object's matrix translation/rotation/scale
        // so that siblings aren't affected!
        glPopMatrix();
    }
}

void SceneObject::updateRecursive(Uint32* deltaTime)
{
    if(updatable)
    {
        update(deltaTime);
        for(unsigned int i = 0; i < children.size(); i++)
        {
            children[i]->updateRecursive(deltaTime);
        }
    }
}

void SceneObject::handleEventsRecursive(SDL_Event* event)
{
    if(eventable)
    {
        handleEvents(event);
        for(unsigned int i = 0; i < children.size(); i++)
        {
            children[i]->handleEventsRecursive(event);
        }
    }
}
